﻿using HandleSign.DataBase.AfterClass;
using HandleSign.DataBase.SignTime;
using HandleSign.models;
using HandleSign.Models;
using HandleSign.utils;
using HandleSign.Utils;
using ServerPA.CompletPort.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace HandleSign
{
    /// <summary>
    /// 程序主逻辑
    /// </summary>
    class SignClient
    {
        public bool isFinish = true; // 是否结束
        public bool isTimerHasStarted = false;
        private bool isFirstData = true;
        public string TimeMarker;

        public SignTimeModels model;  //signtimemodel
        //第一条数据的时间   1、用于update ishandle时的参考时间 （和防止没数据时，阀值时间没有参考物） ;  2、 当没有签到数据时 用于判断事件阈值是否超过时\是否下课 的参考时间 3、 
        public DateTime CurrentTime;
        List<TaskNumModel> tnList = new List<TaskNumModel>(); // 最外层集合   taskNum集合

        //DateTime etime;
        SignTimeDAL stDAL = new SignTimeDAL(Form1.connstr);

        public void client()
        {
            BeginHandle();
            while (isTimerHasStarted)
            {
                isTimerHasStarted = false;
                BeginHandle();
            }
        }


        public void BeginHandle()
        {
            isFinish = false;

            LogUtil.SaveLog("\r\n------------------------------------------------------------------------------开始------------------------------------------------------------------", "Main");
            string TimeInfoStr = string.Empty;
            foreach (TimeInfo t in Form1.timeInfoList)
            {
                TimeInfoStr += "\r\n" + t.toString();
            }
            String logStr = "写入时间：" + DateTime.Now.ToString() + "\r\n" + Form1.sdsModel.ToArray().ToString() + TimeInfoStr;
            LogUtil.SaveLog(logStr, "DataSet");


            stDAL.removeSignTime(); // 迁移SignTime数据
            stDAL.updateIsHandle(2, 0);

            //DataTable dt_SignTime = null ;
            List<SignTimeList> signTimeLists = stDAL.getUserSignTime(TimeMarker); //获取这次所有的SignTime
            isFirstData = true; //更新状态

            TimeMarker = string.IsNullOrEmpty(TimeMarker) ? DateTime.Now.ToString() : TimeMarker; //记录上次最后一条signtime的scantime （只有没有数据时才记录）
            CurrentTime = DateTime.Now; //当没有数据时，用当前时间（每次都记录）
            LogUtil.PrintlnLog("更改前的TimeMarker: ", TimeMarker, "Main");
            LogUtil.PrintlnLog("更改前的CurrentTime: ", CurrentTime.ToString(), "Main");

            tnList = stDAL.handleTaskNumId(tnList);


            if (signTimeLists.Count != 0)
            {

                foreach (SignTimeList signTimeList in signTimeLists)
                {

                    if (signTimeList.signtimes.Count > 0)
                    {
                        List<SystemDataSetModel> sdsModels = Form1.sdsModel.Where(s => s.GroupId.Equals(signTimeList.groupId)).ToList();
                        SystemDataSetModel sdsModel = sdsModels.Count > 0 ? sdsModels[0] : null;

                        //for () {

                        //}
                        //倒序遍历 方便删除list中的元素
                        for (int i = tnList.Count - 1; i >= 0; i--)
                        {
                            SignEven signEven = getNormalEven(tnList[i]);

                            LogUtil.SaveLog("-----------------TaskNum " + i + "--------------------------------", "Main");
                            LogUtil.PrintlnLog("taskNum 信息  ", tnList[i].tostring(), "Main");

                            tnList[i].seList.Remove(signEven);


                            tnList[i].seList.Add(HandleEvenClient(signEven, signTimeList, tnList[i], sdsModel));
                            if (i == 0)
                            {
                                AfterClassClient();
                            }

                        }
                    }
                    else
                    {
                        LogUtil.SaveLog("--------没有签到数据的情况--------", "Main");
                        AfterClassClient();
                    }

                }
            }
            else
            {
                LogUtil.SaveLog("--------没有签到数据的情况--------", "Main");
                AfterClassClient();
            }

            isFinish = true;
        }

        /*********************************************************************************************************************************************************************/

        /// <summary>
        /// 处理单个事件
        /// </summary>
        public SignEven HandleEvenClient(SignEven signeven, SignTimeList signTimeList, TaskNumModel taskNumModel, SystemDataSetModel sdsModel)
        {
            #region  signtime
            List<SignTimeModel> signTimeModels = signTimeList.signtimes.Where(u => u.taskNum.Equals(taskNumModel.taskNumId)).ToList();

            if (signTimeModels.Count > 0)
            {
                //foreach (DataRow dr_SignTime in dr_SignTimeList) {
                for (int i = 0; i < signTimeModels.Count; i++)
                {

                    int userid = Convert.ToInt32(signTimeModels[i].userId);
                    string ScanTime = Convert.ToDateTime(signTimeModels[i].scanTime).ToString("yyyy-MM-dd HH:mm:ss.fff");
                    string SsidScan = signTimeModels[i].ssidScan;

                    List<SignTimeModels> StuList = signeven.Stlist.Where(u => u.userid == userid).ToList();
                    if (StuList.Count == 0)
                    {
                        // userid不存在
                        model = new SignTimeModels();
                        model.userid = userid;
                        model.ScanTime = ScanTime; // 只记录第一条记录？
                    }
                    else
                    {
                        model = StuList[0];
                    }



                    //  int nullSignTimeCount = taskNumModel.taskNumId.Equals("NULL") ? stDAL.getUserId(signeven.ClassId).Where(num => num == model.userid).ToList().Count : 0;
                    //  if (nullSignTimeCount > 0 || !taskNumModel.taskNumId.Equals("NULL"))
                    //  if (!taskNumModel.taskNumId.Equals("NULL")){ 


                    //  下课的情况
                    if (!(signTimeModels[i].taskNum.Equals("NUll") && !taskNumModel.taskNumId.Equals("NULL")))
                    {
                        ///2.3
                    }

                    ///----------------------------------------set Data -------------------------------------------------------
                    //当even的RCtime为空时
                    if (string.IsNullOrEmpty(signeven.Rctime))
                    {
                        signeven.Rctime = ScanTime;
                    }

                    if (isFirstData)
                    {
                        CurrentTime = DateTime.Parse(ScanTime);  // 参考时间（当有数据时，取signTime集合中的第一条）
                        isFirstData = false;
                    }

                    //taskNum中的最后一条数据 （每一个都要获取一次，防止最后一个taskNum的signtime为空的情况）

                    //423     
                    if (i == signTimeModels.Count - 1)
                    {
                        TimeMarker = Convert.ToDateTime(signTimeModels[(signTimeModels.Count) - 1].scanTime).ToString("yyyy-MM-dd HH:mm:ss.fff");
                        LogUtil.PrintlnLog("最后一条数据记录TimeMarker ", TimeMarker, "Main");
                    }
                    ///----------------------------------------set Data -------------------------------------------------------

                    // if (!AfterClassClient())
                    // {

                    //判断签到是否超过有效阈值
                    LogUtil.SaveLog("(有签到信息的情况)判断签到是否超过有效阈值:" + "签到时间：" + Convert.ToDateTime(ScanTime) + "--------ReTime:" + Convert.ToDateTime(signeven.Rctime).AddSeconds(+sdsModel.holdtime), "Main");
                    if (Convert.ToDateTime(ScanTime) >= Convert.ToDateTime(signeven.Rctime).AddSeconds(+sdsModel.holdtime))
                    {
                        LogUtil.SaveLog("写入时间：" + DateTime.Now.ToString() + " ---------------超过阈值了 ---------------------------", "Main");
                        //int ManualSignCount = stDAL.getManualSignCount(taskNumModel.taskNumId,taskNumModel.classList[0]); // 3/29  多个班时需要修改

                        //超过阀值  (正常情况)
                        // string mTaskNumId =  taskNumModel.taskNumId + "_" + taskNumModel.classId; //用于标记事件的名字
                        signeven = HandleEvenUtlis.HandleEven(taskNumModel, signeven, signeven.EvenId, sdsModel, stDAL, ScanTime); // 其保存到tasknum集合


                        //stDAL.updateIsHandle(1, 2, taskNumModel.taskNumId, ScanTime);


                        taskNumModel.seList.Remove(signeven);
                        taskNumModel.seList.Add(signeven);

                        i--; //防止丢失这条数据

                        //  这次事件结束，但是还有数据未处理
                        if (i != signTimeModels.Count - 1)
                        {
                            SignEven newSignEven = new SignEven();
                            newSignEven.EvenId = signeven.EvenId + 1;
                            //newSignEven.ClassId = signeven.ClassId;
                            //  newSignEven.ClassSwitchId = signeven.ClassSwitchId;  //  删除
                            signeven = newSignEven;
                        }
                        // EvenFinishCount++;
                        // taskNumModel.seList.Insert(s + 1, signeven);
                    }
                    else
                    {

                        //未超过阀值
                        //判断学生是否已存在集合里  若存在 则合并。否则 新建
                        // List<SignTimeModels> StuList = signeven.Stlist.Where(u => u.userid == model.userid).ToList();


                        int index = 8 * sdsModel.tercount;//获取前N个保存
                        if (SsidScan.Length > index)
                        {
                            model.SsidList.Add(SsidScan.Substring(0, index - 1));
                        }
                        else
                        {
                            model.SsidList.Add(SsidScan);
                        }


                        if (StuList.Count == 0)
                        {
                            // userId 不存在时
                            signeven.Stlist.Add(model);
                            signeven.Rctime = string.IsNullOrEmpty(signeven.Rctime) ? Convert.ToDateTime(ScanTime).ToString() : TimeUtils.GetRctime(Convert.ToDateTime(signeven.Rctime), Convert.ToDateTime(ScanTime)).ToString();
                        }
                        else
                        {
                            model.ScanTime = ScanTime;
                        }

                    }
                    // }

                }
            }
            // 此taskNum 没有signtime数据时 
            else if (!string.IsNullOrEmpty(signeven.Rctime))
            {

                LogUtil.SaveLog("(此taskNum没有signtime数据的情况)判断签到是否超过有效阈值:" + "签到时间（CurrentTime）：" + Convert.ToDateTime(CurrentTime) + "-------ReTime:" + Convert.ToDateTime(signeven.Rctime).AddSeconds(+sdsModel.holdtime), "Main");
                if (Convert.ToDateTime(CurrentTime) >= Convert.ToDateTime(signeven.Rctime).AddSeconds(+sdsModel.holdtime) && Convert.ToDateTime(CurrentTime) <= Convert.ToDateTime(signeven.Rctime).AddSeconds(-sdsModel.holdtime))  // 后面的条件是否可以不要
                {
                    //int ManualSignCount = stDAL.getManualSignCount(taskNumModel.taskNumId, taskNumModel.classList[0]);
                    // 超过阀值 （没有signtime数据时）
                    //string mTaskNumId = taskNumModel.taskNumId + "_" + taskNumModel.classId; //用于标记事件的名字
                    signeven = HandleEvenUtlis.HandleEven(taskNumModel, signeven, signeven.EvenId, Form1.sdsModel[0], stDAL, CurrentTime.ToString()); // 其保存到tasknum集合

                    // 2/5
                    if (signeven.Stlist.Count > 0)
                    {
                        //stDAL.updateIsHandle(1, 3, taskNumModel.taskNumId, signeven.Stlist[signeven.Stlist.Count - 1].ScanTime);
                        // stDAL.updateIsHandle(1, 2, taskNumModel.taskNumId, CurrentTime.ToString());
                        // stDAL.updateIsHandle(1, 2, taskNumModel.taskNumId);
                    }

                }
            }
            #endregion
            return signeven;
        }

        /*********************************************************************************************************************************************************************/

        public bool AfterClassClient()
        {
            bool isAfterClass = false;

            #region 判断是否下课
            // 获取下了课的TaskNum
            //List<TaskNumModel> afterClassModelList = tnList.Where(u => u.taskNumId != "NULL").ToList().Where(u => Convert.ToDateTime(u.finistTime) < CurrentTime).ToList();

            List<TaskNumModel> afterClassModelList = new List<TaskNumModel>();


            if (tnList != null && tnList.Count > 0)
            {
                foreach (TaskNumModel tnModel in tnList)
                {

                     
                    string time = string.Empty;

                    try
                    {
                        List<SystemDataSetModel> systemDataSetModels = Form1.sdsModel.Where(s => s.GroupId.Equals(tnModel.groupId)).ToList();
                        SystemDataSetModel sdsModel = null;
                        if (systemDataSetModels.Count > 0)
                        {
                            sdsModel = systemDataSetModels[0];
                            LogUtil.SaveLog("写入时间：" + DateTime.Now.ToString() + sdsModel.toString(), "systemDataSetModels");
                        }

                        //string time = Form1.timeInfoList.Where(u => u.timeNum == tnModel.ClassTimeNum).ToList()[0].etime;
                        List<TimeInfo> timeInfoList = Form1.timeInfoList.Where(u => u.timeNum == tnModel.ClassTimeNum && u.groupId == tnModel.groupId).ToList();

                        DateTime etime;
                        time = tnModel.ClassEndTime + " " + timeInfoList[0].etime;
                        etime = Convert.ToDateTime(time).AddSeconds(sdsModel.TimeSetE).AddSeconds(10);

                        LogUtil.PrintlnLog("  拼接下课时间 ", time, "Main");
                        LogUtil.PrintlnLog("用于对比下课的CurrentTime", CurrentTime.ToString(), "Main");

                        //睡前备注： 检查 currenttime在没数据的时侯是否有问题

                        //判断是否下课 
                        if (Convert.ToDateTime(etime) < CurrentTime)
                        {
                            afterClassModelList.Add(tnModel);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogUtil.LogToFile(ex, this.GetType().Name);
                        LogUtil.SaveLog("Exception ------   写入时间：" + DateTime.Now.ToString() + "  time  : " + time + " 用于对比下课的CurrentTime : " + CurrentTime, "Main");
                        // etime = time;
                    }
                }
            }
            #endregion


            #region 处理下课内容
            if (afterClassModelList.Count > 0)
            {
                LogUtil.SaveLog("--------------------------处理下课模块--------------------------", "Main");
                //遍历下课的taskNum。查看是否有未结束的事件
                foreach (TaskNumModel tnModel in afterClassModelList)
                {
                    SystemDataSetModel sdsModel = Form1.sdsModel.Where(s => s.GroupId.Equals(tnModel.groupId)).ToList()[0];

                    DateTime etime;
                    List<TimeInfo> timeInfoList = Form1.timeInfoList.Where(u => u.timeNum == tnModel.ClassTimeNum && u.groupId == tnModel.groupId).ToList();
                    string time = tnModel.ClassEndTime + " " + timeInfoList[0].etime;
                    etime = Convert.ToDateTime(time).AddSeconds(sdsModel.TimeSetE).AddSeconds(10);
                    // 423
                    List<SignEven> nohandleEvenList = tnModel.seList.Where(u => u.EvenStatus == 0 && Convert.ToDateTime(u.Rctime) < Convert.ToDateTime(etime).AddSeconds(sdsModel.TimeSetE).AddSeconds(10) && u.Stlist.Count > 0).ToList();

                    if (nohandleEvenList.Count > 0)
                    {
                        LogUtil.SaveLog("还有未处理的事件", "Main");
                        foreach (SignEven nohandleEven in nohandleEvenList)
                        {
                            SignEven se = HandleEvenUtlis.HandleEven(tnModel, nohandleEven, nohandleEven.EvenId, sdsModel, stDAL, nohandleEven.Stlist[nohandleEven.Stlist.Count - 1].ScanTime); // 其保存到tasknum集合

                            tnModel.seList.Remove(nohandleEven);
                            tnModel.seList.Add(se);
                        }
                    }

                    List<SignEven> EvenList = tnModel.seList.Where(u => u.EvenStatus == 1).ToList();

                    if (EvenList.Count > 0)
                    {
                        AfterClassDAl afterClassDAl = new AfterClassDAl();
                        afterClassDAl.HandleAfterClass(tnModel, stDAL, etime);
                    }
                    else
                    {
                        LogUtil.SaveLog("写入时间：" + DateTime.Now.ToString() + "强制将没处理的signtime的isHandle改为1", "Main");
                        stDAL.updateIsHandle(1, 2, tnModel.taskNumId, DateTime.Now.ToString());
                    }
                    isAfterClass = true;
                    tnList.Remove(tnModel);

                }

            }

            if (tnList.Count > 0 && tnList != null)
            {
                // 防止事件不结束
                foreach (TaskNumModel tnModel in tnList)
                {
                    try {

                        List<SystemDataSetModel> systemDataSetModels = Form1.sdsModel.Where(s => s.GroupId.Equals(tnModel.groupId)).ToList();
                        SystemDataSetModel sdsModel = null;
                        if (systemDataSetModels.Count > 0)
                        {
                            sdsModel = systemDataSetModels[0];
                            LogUtil.SaveLog("写入时间：" + DateTime.Now.ToString() + sdsModel.toString(), "systemDataSetModels");
                        }

                        List<SignEven> sel = tnModel.seList.Where(v => v.EvenStatus == 0).ToList();
                        if (sel.Count > 0)
                        {
                            ////判断签到是否超过有效阈值
                            LogUtil.SaveLog("(一条signtime数据都没有的情况)判断签到是否超过有效阈值:" + "签到时间（CurrentTime）：" + CurrentTime + "------ReTime:" + Convert.ToDateTime(sel[0].Rctime).AddSeconds(+sdsModel.holdtime), "Main");
                            if (CurrentTime >= Convert.ToDateTime(sel[0].Rctime).AddSeconds(+sdsModel.holdtime))
                            {
                                HandleEvenUtlis.HandleEven(tnModel, sel[0], sel[0].EvenId, sdsModel, stDAL, CurrentTime.ToString()); // 其保存到tasknum集合 
                            }
                        }
                    }

                    catch (Exception ex)
                    {
                        LogUtil.LogToFile(ex, this.GetType().Name);
                        // etime = time;
                    }
                }
            }

            //  处理只有老师手动签到的情况。
            stDAL.HandleManualSign(CurrentTime.ToString());


            return isAfterClass;
            #endregion


        }

        /*********************************************************************************************************************************************************************/


        /// <summary>
        /// 获取正常taskNum要处理的事件
        /// </summary>
        /// <param name="taskNumModel"></param>
        /// <returns></returns>
        public SignEven getNormalEven(TaskNumModel taskNumModel)
        {

            SignEven signEven = new SignEven();

            #region 新建事件
            // 1,处理 事件 （若有上次未完成的事件，则继续完成。 若无，则新建）

            // TaskNum 为空的 后面再处理
            if (taskNumModel.seList.Where(u => u.EvenStatus == 0).ToList().Count == 1)
            {
                // 有未完成
                signEven = (taskNumModel.seList.Where(u => u.EvenStatus == 0).ToList())[0];
                // tnList[i].seList.Remove(signeven);
            }
            else
            {
                // 无未完成 或  无事件
                if (taskNumModel.seList.Count == 0)
                {
                    //无事件
                    signEven.EvenId = 0;
                }
                else
                {
                    List<SignEven> seListFor1 = taskNumModel.seList.Where(u => u.EvenStatus == 1 || u.EvenStatus == 2).ToList();
                    signEven.EvenId = seListFor1[seListFor1.Count - 1].EvenId + 1;
                }
            }
            #endregion

            return signEven;
        }
    }
}